package cn.lg.soar.boot.fc.service.impl;

import cn.lg.soar.boot.fc.constants.RoomConstant;
import cn.lg.soar.boot.fc.entity.*;
import cn.lg.soar.boot.fc.entity.bo.ChangeBo;
import cn.lg.soar.boot.fc.entity.bo.RoomBo;
import cn.lg.soar.boot.fc.entity.importExcel.RoomIo;
import cn.lg.soar.boot.fc.entity.vo.*;
import cn.lg.soar.boot.fc.params.RoomParams;
import cn.lg.soar.boot.fc.service.*;
import cn.lg.soar.boot.fc.tool.RoomValidation;
import cn.lg.soar.common.data.msg.I18n;
import cn.lg.soar.common.model.HttpResult;
import cn.lg.soar.common.model.PageQuery;
import cn.lg.soar.common.model.PageResult;
import cn.lg.soar.common.util.AssertUtil;
import cn.lg.soar.common.util.ParameterUtil;
import cn.lg.soar.core.util.easyexcel.ExcelUtil;
import cn.lg.soar.database.query.QueryParams;
import cn.lg.soar.database.query.SqueryWapper;
import cn.lg.soar.system.general.entity.DictItem;
import cn.lg.soar.system.general.service.IDictItemService;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import io.micrometer.core.instrument.util.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.lg.soar.database.base.service.impl.BaseServiceImpl;
import cn.lg.soar.boot.fc.mapper.RoomMapper;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;

/**
 * 房间表
 * @author ZhuanZ（无密码）
 * @since 2025-01-14
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
@Service
public class RoomServiceImpl extends BaseServiceImpl<RoomMapper, Room> implements RoomService {

    @Autowired
    private CampusService campusService;

    @Autowired
    private BuildingService buildingService;

    @Autowired
    private UnitService unitService;

    @Autowired
    private FloorService floorService;

    @Autowired
    private ChangeService changeService;

    @Autowired
    private IDictItemService iDictItemService;

    @Autowired
    private RentService rentService;

    @Autowired
    private LesseemanageService lesseemanageService;

    @Autowired
    private ContractTemplateService contractTemplateService;

    // 房产类型，写死，后期像用配置文件的话打开下面
//    @Value("${fcRoom.typeId}")
    public String roomTypeId = "1881521867918880769";

    @Override
    public HttpResult<Serializable> create(RoomBo roomBo) {

        ParameterUtil.notNull(roomBo, "数据不能为空");

        // 关联校区楼栋等不可为空 其实没用，bo有限制。
        if (StringUtils.isBlank(roomBo.getParentId())) {
            return HttpResult.fail("4000", "关联校区信息不为空", "error");
        }

        // 参数效验
        if (!RoomValidation.checkElevator(roomBo.getIsElevator())) {
            return HttpResult.fail("4000", "是否有电梯 参数不正确", "error");
        }

        if (!RoomValidation.checkFloorType(roomBo.getFloorType())) {
            return HttpResult.fail("4000", "楼层类型 参数不正确", "error");
        }

        if (!RoomValidation.checkRoomType(roomBo.getRoomType())) {
            return HttpResult.fail("4000", "房间类型 参数不正确", "error");
        }

        if (!RoomValidation.checkPayWay(roomBo.getPayWay())) {
            return HttpResult.fail("4000", "付费方式 参数不正确", "error");
        }

        if (!RoomValidation.checkTenancyWay(roomBo.getTenancyWay())) {
            return HttpResult.fail("4000", "租房方式 参数不正确", "error");
        }

        if (!RoomValidation.checkUseState(roomBo.getUseState())) {
            return HttpResult.fail("4000", "使用状态 参数不正确", "error");
        }

        if (!RoomValidation.checkIsFull(roomBo.getIsFull())) {
            return HttpResult.fail("4000", "是否组满 参数不正确", "error");
        }

        if (!RoomValidation.checkIsRent(roomBo.getIsRent())) {
            return HttpResult.fail("4000", "租金模式 参数不正确", "error");
        }
        // 其实没用，bo有限制 end。

        if (RoomConstant.RENT_ZERO == roomBo.getIsRent() && StringUtils.isBlank(roomBo.getRent())) {
            return HttpResult.fail("4000", "租金 参数不可为空", "error");
        } else if (RoomConstant.RENT_ONE == roomBo.getIsRent() && Objects.isNull(roomBo.getRentId())) {
            return HttpResult.fail("4000", "租金模式绑定 参数不正确", "error");
        }
        if (StringUtils.isBlank(roomBo.getRent())) {
            roomBo.setRent("0");
        }

        Room room = new Room();
        BeanUtils.copyProperties(roomBo, room);

        // 父级的参数 关联
        String parentId = roomBo.getParentId();
        // 祖宗
        String campusIdSearch = "";
        String buildingIdSearch = "";
        String unitIdSearch = "";
        String floorIdSearch = "";

        // 1-3-0-0
        String[] searchStr = parentId.split("-");

        if (4 <= searchStr.length) {
            campusIdSearch = !"0".equals(searchStr[0]) ? searchStr[0]: "";
            buildingIdSearch = !"0".equals(searchStr[1]) ? searchStr[1]: "";
            unitIdSearch = !"0".equals(searchStr[2]) ? searchStr[2]: "";
            floorIdSearch = !"0".equals(searchStr[3]) ? searchStr[3]: "";
        }

        if (StringUtils.isNotBlank(campusIdSearch)) {
            room.setCampusId(Long.valueOf(campusIdSearch));
        }
        if (StringUtils.isNotBlank(buildingIdSearch)) {
            room.setBuildingId(Long.valueOf(buildingIdSearch));
        }
        if (StringUtils.isNotBlank(unitIdSearch)) {
            room.setUnitId(Long.valueOf(unitIdSearch));
        }
        if (StringUtils.isNotBlank(floorIdSearch)) {
            room.setFloorId(Long.valueOf(floorIdSearch));
        }

        boolean checkFlag =
                StringUtils.isBlank(campusIdSearch) || StringUtils.isBlank(buildingIdSearch) || StringUtils.isBlank(unitIdSearch) || StringUtils.isBlank(floorIdSearch);

        if (checkFlag) {
            return HttpResult.fail("4000", "房间关联层级不正确，请重新选择", "error");
        }

        // 父级的参数 关联 end

        AssertUtil.isTrue(this.save(room), "创建失败");
        return HttpResult.<Serializable>success("创建成功").setData("success");
    }

    @Override
    public HttpResult<Void> update(RoomBo roomBo) {
        ParameterUtil.notNull(roomBo, "数据不能为空");

        // 获取旧的数据对象，
        Room oldRoom = this.getData(roomBo.getId());

        if (RoomConstant.RENT_ZERO == roomBo.getIsRent() && StringUtils.isBlank(roomBo.getRent())) {
            return HttpResult.fail("4000", "租金 参数不可为空", "error");
        } else if (RoomConstant.RENT_ONE == roomBo.getIsRent() && Objects.isNull(roomBo.getRentId())) {
            return HttpResult.fail("4000", "租金模式绑定 参数不正确", "error");
        }
        if (StringUtils.isBlank(roomBo.getRent())) {
            roomBo.setRent("0");
        }

        Room room = new Room();
        BeanUtils.copyProperties(roomBo, room);

        // 父级的参数 关联
        String parentId = roomBo.getParentId();
        // 祖宗
        String campusIdSearch = "";
        String buildingIdSearch = "";
        String unitIdSearch = "";
        String floorIdSearch = "";

        // 1-3-0-0
        String[] searchStr = parentId.split("-");
        if (4 <= searchStr.length) {
            campusIdSearch = !"0".equals(searchStr[0]) ? searchStr[0]: "";
            buildingIdSearch = !"0".equals(searchStr[1]) ? searchStr[1]: "";
            unitIdSearch = !"0".equals(searchStr[2]) ? searchStr[2]: "";
            floorIdSearch = !"0".equals(searchStr[3]) ? searchStr[3]: "";
        }

        if (StringUtils.isNotBlank(campusIdSearch)) {
            room.setCampusId(Long.valueOf(campusIdSearch));
        }
        if (StringUtils.isNotBlank(buildingIdSearch)) {
            room.setBuildingId(Long.valueOf(buildingIdSearch));
        }
        if (StringUtils.isNotBlank(unitIdSearch)) {
            room.setUnitId(Long.valueOf(unitIdSearch));
        }
        if (StringUtils.isNotBlank(floorIdSearch)) {
            room.setFloorId(Long.valueOf(floorIdSearch));
        }

        boolean checkFlag =
                StringUtils.isBlank(campusIdSearch) || StringUtils.isBlank(buildingIdSearch) || StringUtils.isBlank(unitIdSearch) || StringUtils.isBlank(floorIdSearch);

        if (checkFlag) {
            return HttpResult.fail("4000", "房间关联层级不正确，请重新选择", "error");
        }
        // 父级的参数 关联 end

        AssertUtil.isTrue(this.updateById(room), "更新失败");

        // 结果为真，生成变更记录信息


        ChangeBo changeBo = new ChangeBo();

        changeBo.setRoomCode(room.getRoomCode());
        changeBo.setRoomId(room.getId());
        changeBo.setChangeU(room.getCreateBy());

        // 修改的字段json串儿
        JSONArray messageArr = getChangeArrJSON (oldRoom, room);

        changeBo.setMessage(messageArr.toJSONString());
        changeService.create(changeBo);

        return HttpResult.success("更新成功");
    }

    @Override
    public Room getData(Long id) {
        if (Objects.isNull(id)) {
            return new Room();
        }
        Room room = this.getOne(Wrappers.<Room>lambdaQuery().eq(Room::getId, id));
        if (null == room) {
            room = new Room();
        }
        return room;
    }

    @Override
    public RoomVo getVoData(Long id) {
        RoomVo roomVo = new RoomVo();

        if (Objects.isNull(id)) {
            return roomVo;
        }

        Room room = this.getData(id);
        BeanUtils.copyProperties(room, roomVo);

        // 需要的校区数据
        CampusEasyVo campusEasyVo = campusService.getEasyVoData(roomVo.getCampusId());
        roomVo.setCampusEasyVo(campusEasyVo);

        // 简单的楼栋信息
        BuildingEasyVo buildingEasyVo = buildingService.getEasyVoData(roomVo.getBuildingId());
        roomVo.setBuildingEasyVo(buildingEasyVo);

        // 简单的单元信息
        UnitEasyVo unitEasyVo = unitService.getEasyVoData(roomVo.getUnitId());
        roomVo.setUnitEasyVo(unitEasyVo);

        // 简单的楼层信息
        FloorEasyVo floorEasyVo = floorService.getEasyVoData(roomVo.getFloorId());
        roomVo.setFloorEasyVo(floorEasyVo);

        return roomVo;
    }

    @Override
    public RoomEasyVo getEasyVoData(Long id) {
        RoomEasyVo roomEasyVo = new RoomEasyVo();

        if (Objects.isNull(id)) {
            return roomEasyVo;
        }

        Room room = this.getData(id);
        BeanUtils.copyProperties(room, roomEasyVo);
        return roomEasyVo;
    }

    @Override
    public PageResult<RoomVo> queryResultVo(PageQuery pageQuery, QueryParams params, RoomParams roomParams) {
        PageResult<RoomVo> pageResultVo = new PageResult<>();

        SqueryWapper<Room> squeryWapper = new SqueryWapper<>(Room.class);

        // 树状菜单检索兼容page检索
        if (StringUtils.isNotBlank(roomParams.getSearchIds())) {

            // 祖宗
            String campusIdSearch = "";
            String buildingIdSearch = "";
            String unitIdSearch = "";
            String floorIdSearch = "";

            // 1-3-0-0
            String[] searchStr = roomParams.getSearchIds().split("-");

            if (4 >= searchStr.length) {
                campusIdSearch = !"0".equals(searchStr[0]) ? searchStr[0]: "";
                buildingIdSearch = !"0".equals(searchStr[1]) ? searchStr[1]: "";
                unitIdSearch = !"0".equals(searchStr[2]) ? searchStr[2]: "";
                floorIdSearch = !"0".equals(searchStr[3]) ? searchStr[3]: "";
            }

            List<String> f = params.getF();

            if (null == f || f.isEmpty()) {
                f = new ArrayList<>();
            }

            if (StringUtils.isNotBlank(campusIdSearch)) {
                f.add("campusId-like~" + campusIdSearch);
            }
            if (StringUtils.isNotBlank(buildingIdSearch)) {
                f.add("buildingId-like~" + buildingIdSearch);
            }
            if (StringUtils.isNotBlank(unitIdSearch)) {
                f.add("unitId-like~" + unitIdSearch);
            }
            if (StringUtils.isNotBlank(floorIdSearch)) {
                f.add("floorId-like~" + floorIdSearch);
            }

            params.setF(f);
        }

        PageResult<Room> pageResult = squeryWapper.query(this, pageQuery, params);
        // 对象拷贝
        BeanUtils.copyProperties(pageResult, pageResultVo);

        // vo封装
        List<RoomVo> list = new ArrayList<>();
        pageResult.getList().forEach(item-> {

            RoomVo roomVo = new RoomVo();
            BeanUtils.copyProperties(item, roomVo);

            // 其他 简单vo的数据封装
            // 需要的校区数据
            CampusEasyVo campusEasyVo = campusService.getEasyVoData(roomVo.getCampusId());
            roomVo.setCampusEasyVo(campusEasyVo);

            // 简单的楼栋信息
            BuildingEasyVo buildingEasyVo = buildingService.getEasyVoData(roomVo.getBuildingId());
            roomVo.setBuildingEasyVo(buildingEasyVo);

            // 简单的单元信息
            UnitEasyVo unitEasyVo = unitService.getEasyVoData(roomVo.getUnitId());
            roomVo.setUnitEasyVo(unitEasyVo);

            // 简单的楼层信息
            FloorEasyVo floorEasyVo = floorService.getEasyVoData(roomVo.getFloorId());
            roomVo.setFloorEasyVo(floorEasyVo);

            list.add(roomVo);
        });

        pageResultVo.setList(list);
        return pageResultVo;
    }

    @Override
    public List<Room> getListByOtherId(QueryParams params) {

        List<Room> list = new ArrayList<>();

        // 架构get 请求参数格式：
//        [name-like~楼栋1, area-like~100]
        List<String> f = params.getF();
        if (3 >= f.size()) {
            return list;
        }

        String campusIdStr = f.get(0);
        String buildingIdStr = f.get(1);
        String unitIdStr = f.get(2);
        String floorIdStr = f.get(3);
        if (-1 >= campusIdStr.indexOf("campusId")) {
            return list;
        }
        if (-1 >= buildingIdStr.indexOf("buildingId")) {
            return list;
        }
        if (-1 >= unitIdStr.indexOf("unitId")) {
            return list;
        }

        if (-1 >= floorIdStr.indexOf("floorId")) {
            return list;
        }

        String[] campTemp = campusIdStr.split(params.VALUE_JOIN);
        String[] buildTemp = buildingIdStr.split(params.VALUE_JOIN);
        String[] unitTemp = unitIdStr.split(params.VALUE_JOIN);
        String[] floorTemp = floorIdStr.split(params.VALUE_JOIN);

        if (1 >= campTemp.length || 1 >= buildTemp.length || 1 >= unitTemp.length || -1 >= floorTemp.length) {
            return list;
        }

        String campusId = campTemp[1];
        String buildingId = buildTemp[1];
        String unitId = unitTemp[1];
        String floorId = floorTemp[1];

        list =
                list(Wrappers.<Room>lambdaQuery().eq(Room::getCampusId, campusId).eq(Room::getBuildingId, buildingId).eq(Room::getUnitId, unitId).eq(Room::getFloorId, floorId));
        return list;
    }

    @Override
    public FcStatisticsVo getStatistics(Long campusId) {
        FcStatisticsVo fcStatisticsVo = new FcStatisticsVo();

        LambdaQueryWrapper<Room> lambdaQueryWrapper = Wrappers.<Room>lambdaQuery();

        if (!Objects.isNull(campusId)) {
            lambdaQueryWrapper.eq(Room::getCampusId, campusId);
        }

        List<Room> list = this.list(lambdaQueryWrapper);

        if (0 >= list.size()) {
            fcStatisticsVo.setDataCount("0");
            fcStatisticsVo.setDataPlan("0");
            fcStatisticsVo.setDataUse("0");
            return fcStatisticsVo;
        }

        AtomicReference<Float> plan = new AtomicReference<>((float) 0);
        AtomicReference<Float> use = new AtomicReference<>((float) 0);
        statisticsHelper(list, plan, use);

        // 数据总数
        fcStatisticsVo.setDataCount(String.valueOf(list.size()));
        fcStatisticsVo.setDataPlan(String.valueOf(plan.get()));
        fcStatisticsVo.setDataUse(String.valueOf(use.get()));
        return fcStatisticsVo;
    }

    @Override
    public PageResult<FcStatisticsVo> queryResultRoomTypeStaVo(PageQuery pageQuery, QueryParams params, RoomParams roomParams) {

        PageResult<FcStatisticsVo> pageResultVo = new PageResult<>();

        List<FcStatisticsVo> listVo = new ArrayList<>();



        // 查询数据字典对应的 类型信息。 字典id roomTypeId;
        LambdaQueryWrapper<DictItem> dictLambdaQueryWrapper = Wrappers.<DictItem>lambdaQuery();
        Page<DictItem> page = new Page<>(pageQuery.getPageNo(), pageQuery.getPageSize());
        Page<DictItem> dictItemPage = iDictItemService.page(page, dictLambdaQueryWrapper.eq(DictItem::getDictId,
                roomTypeId));


        dictItemPage.getRecords().forEach(dictItem -> {
            // 类型的value, 对应检索对象的type
            int type = dictItem.getValue();

            List<Room> roomList = new ArrayList<>();

            if (StringUtils.isNotBlank(roomParams.getSearchIds())) {
                roomList = list(Wrappers.<Room>lambdaQuery().eq(Room::getRoomType, type).eq(Room::getCampusId,
                        roomParams.getSearchIds()));
            } else {
                roomList = list(Wrappers.<Room>lambdaQuery().eq(Room::getRoomType, type));
            }
            AtomicReference<Float> plan = new AtomicReference<>((float) 0);
            AtomicReference<Float> use = new AtomicReference<>((float) 0);
            statisticsHelper(roomList, plan, use);

            FcStatisticsVo fcStatisticsVo = new FcStatisticsVo();
            fcStatisticsVo.setName(dictItem.getLabel());
            fcStatisticsVo.setDataCount(String.valueOf(roomList.size()));
            fcStatisticsVo.setDataPlan(String.valueOf(plan));
            fcStatisticsVo.setDataUse(String.valueOf(use));

            listVo.add(fcStatisticsVo);
        });

        pageResultVo.setPageNo(pageQuery.getPageNo());
        pageResultVo.setPageSize(pageQuery.getPageSize());
        pageResultVo.setTotal(Long.valueOf(page.getTotal()));
        pageResultVo.setList(listVo);
        return pageResultVo;
    }

    @Override
    public void exportExcel(String filename, QueryParams params, HttpServletResponse resp) {
        SqueryWapper<Room> squeryWapper = new SqueryWapper<>(Room.class);

        if (null == squeryWapper) {
            squeryWapper = new SqueryWapper<>(Room.class);
        }
        QueryWrapper<Room> wrapper = Wrappers.query();
        squeryWapper.setWhere(params.getF(), wrapper);
        squeryWapper.setSelect(params.getFields(), wrapper);
        squeryWapper.setOrderBy(params.getOrderBy(), wrapper);

        List<Room> list = new ArrayList<>();
        List<RoomIo> listIo = new ArrayList<>();
        if (null == params.getF()) {
            list.add(new Room());
            listIo.add(new RoomIo());
        } else {
            list = this.list(wrapper);
        }

        list.forEach(item->{
            Room room = this.getData(item.getId());

            RoomIo roomIo = new RoomIo();
            BeanUtils.copyProperties(item, roomIo);
            roomIo.setCampusName(campusService.getEasyVoData(room.getCampusId()).getName());
            roomIo.setBuildingName(buildingService.getEasyVoData(room.getBuildingId()).getName());
            roomIo.setUnitName(unitService.getEasyVoData(room.getUnitId()).getName());
            roomIo.setFloorName(floorService.getEasyVoData(room.getFloorId()).getName());

            if (!Objects.isNull(room.getContractTemplateId())) {
                ContractTemplate contractTemplate = contractTemplateService.getById(room.getContractTemplateId());
                if (null != contractTemplate) {
                    roomIo.setTemplateName(contractTemplate.getName());
                }
            }

            if (!Objects.isNull(room.getRentId())) {
                Rent rent = rentService.getOneById(room.getRentId());
                if (null != rent) {
                    roomIo.setRentName(rent.getName());
                }
            }

            if (!Objects.isNull(room.getLesseemanageId())) {
                Lesseemanage lesseemanage = lesseemanageService.getOneById(room.getLesseemanageId());
                if (null != lesseemanage) {
                    roomIo.setLesseeManageName(lesseemanage.getName());
                }
            }
            listIo.add(roomIo);
        });

        if (StringUtils.isBlank(filename)) {
            filename = "房间";
        }

        // 导出
        ExcelUtil.exportExcel(filename, listIo, resp);

    }

    @Override
    public HttpResult<Void> importExcel(MultipartFile files) {
        List<RoomIo> dataList;
        try {
            dataList = EasyExcel.read(files.getInputStream()).head(RoomIo.class).sheet()
                    .doReadSync();
        } catch (Exception e) {
            return HttpResult.fail("B0000", I18n.build("数据格式存在问题，无法读取！"));
        }
        if (0 >= dataList.size()) {
            return HttpResult.fail("B0000", I18n.build("无数据，无法读取！"));
        }

        AtomicInteger successNum = new AtomicInteger();
        AtomicInteger errorNum = new AtomicInteger();
        dataList.forEach(item-> {
            importExcelHelper(item, successNum, errorNum);
        });

        String message = "总数：" + dataList.size() + "; 成功：" + successNum.get() + "; 失败：" + errorNum.get();
        return HttpResult.success("导入成功 " + message);
    }

    @Override
    public HttpResult<Serializable> updateSort(List<Map<String, Integer>> sortedData) {

        if (null == sortedData || 0 >= sortedData.size()) {
            return HttpResult.fail("4000", "排序数据不可为空", "error");
        }

        sortedData.forEach(item-> {

            if (!item.containsKey("id") || !item.containsKey("orders")) {
                return;
            }

            Long id = item.get("id").longValue();;
            int orders = item.get("orders");

            Room room = new Room();
            room.setId(id);
            room.setOrders(orders);
            this.updateById(room);
        });
        return HttpResult.success("排序成功");
    }

    /**
     * 新旧参数变更记录
     * @param oldRoom
     * @param room
     * @return
     */
    private JSONArray getChangeArrJSON (Room oldRoom, Room room) {
        JSONArray messageArr = new JSONArray();
        if (null != oldRoom.getId()) {

            JSONObject message = new JSONObject();
            // 校区有没有发生变化
            boolean checkChange =
                    !oldRoom.getCampusId().equals(room.getCampusId()) || !oldRoom.getBuildingId().equals(room.getBuildingId()) || !oldRoom.getUnitId().equals(room.getUnitId()) || !oldRoom.getFloorId().equals(room.getFloorId());

            if (checkChange) {
                message = new JSONObject();

                // 校区
                Campus oldCampus = campusService.getData(oldRoom.getCampusId());
                Campus newCampus = campusService.getData(room.getCampusId());

                // 楼栋
                Building oldBuilding = buildingService.getData(oldRoom.getBuildingId());
                Building newBuilding = buildingService.getData(room.getBuildingId());

                // 单元
                Unit oldUnit = unitService.getData(oldRoom.getUnitId());
                Unit newUnit = unitService.getData(room.getUnitId());

                // 楼层
                Floor oldFloor = floorService.getData(oldRoom.getFloorId());
                Floor newFloor = floorService.getData(room.getFloorId());

                message.put("name", "校区楼栋");
                message.put("oldName", oldCampus.getName() + "-" + oldBuilding.getName() + "-" + oldUnit.getName() + "-" + oldFloor.getName());
                message.put("newName", newCampus.getName() + "-" + newBuilding.getName() + "-" + newUnit.getName() + "-" + newFloor.getName());
                messageArr.add(message);
            }

            if (!Objects.equals(oldRoom.getRoomCode(), room.getRoomCode())) {

                message = new JSONObject();
                message.put("name", "房号");
                message.put("oldName", StringUtils.isNotBlank(oldRoom.getRoomCode()) ? oldRoom.getRoomCode() : "暂无");
                message.put("newName", StringUtils.isNotBlank(room.getRoomCode()) ? room.getRoomCode() : "暂无");
                messageArr.add(message);
            }

            if (!Objects.equals(oldRoom.getImg(), room.getImg())) {

                message = new JSONObject();
                message.put("name", "房屋图片");
                message.put("oldName", StringUtils.isNotBlank(oldRoom.getImg()) ? oldRoom.getImg(): "暂无");
                message.put("newName", StringUtils.isNotBlank(room.getImg()) ? room.getImg(): "暂无");
                messageArr.add(message);
            }

            if (!Objects.equals(oldRoom.getVr(), room.getVr())) {

                message = new JSONObject();
                message.put("name", "房屋VR");
                message.put("oldName", StringUtils.isNotBlank(oldRoom.getVr()) ? oldRoom.getVr(): "暂无");
                message.put("newName", StringUtils.isNotBlank(room.getVr()) ? room.getVr(): "暂无");
                messageArr.add(message);
            }

            if (!Objects.equals(oldRoom.getArea(), room.getArea())) {

                message = new JSONObject();
                message.put("name", "房屋面积");
                message.put("oldName", StringUtils.isNotBlank(oldRoom.getArea()) ? oldRoom.getArea(): "暂无");
                message.put("newName", StringUtils.isNotBlank(room.getArea()) ? room.getArea(): "暂无");
                messageArr.add(message);
            }

            if (!Objects.equals(oldRoom.getLivingRoom(), room.getLivingRoom())) {

                message = new JSONObject();
                message.put("name", "居室");
                message.put("oldName", StringUtils.isNotBlank(oldRoom.getLivingRoom()) ? oldRoom.getLivingRoom(): "暂无");
                message.put("newName", StringUtils.isNotBlank(room.getLivingRoom()) ? room.getLivingRoom(): "暂无");
                messageArr.add(message);
            }

            if (!Objects.equals(oldRoom.getOrient(), room.getOrient())) {

                message = new JSONObject();
                message.put("name", "朝向");
                message.put("oldName", StringUtils.isNotBlank(oldRoom.getOrient()) ? oldRoom.getOrient(): "暂无");
                message.put("newName", StringUtils.isNotBlank(room.getOrient()) ? room.getOrient(): "暂无");
                messageArr.add(message);
            }

            if (!oldRoom.getIsElevator().equals(room.getIsElevator())) {

                message = new JSONObject();
                message.put("name", "是否有电梯");
                message.put("oldName", RoomConstant.ELEVATOR_ONE == oldRoom.getIsElevator() ? "有": "无");
                message.put("newName", RoomConstant.ELEVATOR_ONE == room.getIsElevator() ? "有": "无");
                messageArr.add(message);
            }

            if (!oldRoom.getFloorType().equals(room.getFloorType())) {
                String oldType = "低楼层";
                if (RoomConstant.FLOOR_TYPE_ONE == oldRoom.getFloorType()) {
                    oldType = "中楼层";
                } else if (RoomConstant.FLOOR_TYPE_TWO == oldRoom.getFloorType()) {
                    oldType = "高楼层";
                }
                String newType = "低楼层";
                if (RoomConstant.FLOOR_TYPE_ONE == room.getFloorType()) {
                    newType = "中楼层";
                } else if (RoomConstant.FLOOR_TYPE_TWO == room.getFloorType()) {
                    newType = "高楼层";
                }
                message = new JSONObject();
                message.put("name", "楼层类型");
                message.put("oldName", oldType);
                message.put("newName", newType);
                messageArr.add(message);
            }


            if (!oldRoom.getRoomType().equals(room.getRoomType())) {

                String oldType = "周转房";
                if (RoomConstant.ROOM_TYPE_ONE == oldRoom.getRoomType()) {
                    oldType = "住宅";
                }
                String newType = "周转房";
                if (RoomConstant.ROOM_TYPE_ONE == room.getRoomType()) {
                    newType = "住宅";
                }

                message = new JSONObject();
                message.put("name", "房间类型");
                message.put("oldName", oldType);
                message.put("newName", newType);
                messageArr.add(message);
            }

            if (!Objects.equals(oldRoom.getOwnershipCode(), room.getOwnershipCode())) {

                message = new JSONObject();
                message.put("name", "产权证号");
                message.put("oldName", StringUtils.isNotBlank(oldRoom.getOwnershipCode()) ? oldRoom.getOwnershipCode(): "暂无");
                message.put("newName", StringUtils.isNotBlank(room.getOwnershipCode()) ? room.getOwnershipCode(): "暂无");
                messageArr.add(message);
            }

            if (!oldRoom.getPayWay().equals(room.getPayWay())) {

                String oldMess = "月付";
                if (RoomConstant.PAY_WAY_ONE == oldRoom.getPayWay()) {
                    oldMess = "季付";
                } else if (RoomConstant.PAY_WAY_TWO == oldRoom.getPayWay()) {
                    oldMess = "半年付";
                } else if (RoomConstant.PAY_WAY_THREE == oldRoom.getPayWay()) {
                    oldMess = "年付";
                } else if (RoomConstant.PAY_WAY_FOUR == oldRoom.getPayWay()) {
                    oldMess = "其他";
                }

                String newMess = "月付";
                if (RoomConstant.PAY_WAY_ONE == room.getPayWay()) {
                    newMess = "季付";
                } else if (RoomConstant.PAY_WAY_TWO == room.getPayWay()) {
                    newMess = "半年付";
                } else if (RoomConstant.PAY_WAY_THREE == room.getPayWay()) {
                    newMess = "年付";
                } else if (RoomConstant.PAY_WAY_FOUR == room.getPayWay()) {
                    newMess = "其他";
                }

                message = new JSONObject();
                message.put("name", "付费方式");
                message.put("oldName", oldMess);
                message.put("newName", newMess);
                messageArr.add(message);
            }

            if (!Objects.equals(oldRoom.getRent(), room.getRent())) {

                message = new JSONObject();
                message.put("name", "月租金");
                message.put("oldName", StringUtils.isNotBlank(oldRoom.getRent()) ? oldRoom.getRent(): "暂无");
                message.put("newName", StringUtils.isNotBlank(room.getRent()) ? room.getRent(): "暂无");
                messageArr.add(message);
            }

            if (!oldRoom.getTenancyWay().equals(room.getTenancyWay())) {

                String oldMess = "整租";
                if (RoomConstant.TENANCY_WAY_ONE == oldRoom.getTenancyWay()) {
                    oldMess = "合租";
                }

                String newMess = "整租";
                if (RoomConstant.TENANCY_WAY_ONE == room.getTenancyWay()) {
                    newMess = "合租";
                }

                message = new JSONObject();
                message.put("name", "租房方式");
                message.put("oldName", oldMess);
                message.put("newName", newMess);
                messageArr.add(message);
            }

            if (!oldRoom.getUseState().equals(room.getUseState())) {


                String oldMess = "空置";
                if (RoomConstant.USE_STATE_ONE == oldRoom.getUseState()) {
                    oldMess = "待签约";
                } else if (RoomConstant.USE_STATE_TWO == oldRoom.getUseState()) {
                    oldMess = "已租";
                } else if (RoomConstant.USE_STATE_THREE == oldRoom.getUseState()) {
                    oldMess = "维修中";
                } else if (RoomConstant.USE_STATE_FOUR == oldRoom.getUseState()) {
                    oldMess = "不能居住";
                }

                String newMess = "空置";
                if (RoomConstant.USE_STATE_ONE == room.getUseState()) {
                    newMess = "待签约";
                } else if (RoomConstant.USE_STATE_TWO == room.getUseState()) {
                    newMess = "已租";
                } else if (RoomConstant.USE_STATE_THREE == room.getUseState()) {
                    newMess = "维修中";
                } else if (RoomConstant.USE_STATE_FOUR == room.getUseState()) {
                    newMess = "不能居住";
                }

                message = new JSONObject();
                message.put("name", "使用状态");
                message.put("oldName", oldMess);
                message.put("newName", newMess);
                messageArr.add(message);
            }

            if (!oldRoom.getIsFull().equals(room.getIsFull())) {

                message = new JSONObject();
                message.put("name", "是否租满");
                message.put("oldName", RoomConstant.FULL_ONE == oldRoom.getIsFull() ? "已满": "未满");
                message.put("newName", RoomConstant.FULL_ONE == room.getIsFull() ? "已满": "未满");
                messageArr.add(message);
            }

            if (!Objects.equals(oldRoom.getContacts(), room.getContacts())) {

                message = new JSONObject();
                message.put("name", "联系人");
                message.put("oldName", StringUtils.isNotBlank(oldRoom.getContacts()) ? oldRoom.getContacts(): "暂无");
                message.put("newName", StringUtils.isNotBlank(room.getContacts()) ? room.getContacts(): "暂无");
                messageArr.add(message);
            }

            if (!Objects.equals(oldRoom.getPhone(), room.getPhone())) {

                message = new JSONObject();
                message.put("name", "联系电话");
                message.put("oldName", StringUtils.isNotBlank(oldRoom.getPhone()) ? oldRoom.getPhone(): "暂无");
                message.put("newName", StringUtils.isNotBlank(room.getPhone()) ? room.getPhone(): "暂无");
                messageArr.add(message);
            }

            if (!Objects.equals(oldRoom.getAttachment(), room.getAttachment())) {

                message = new JSONObject();
                message.put("name", "附件");
                message.put("oldName", StringUtils.isNotBlank(oldRoom.getAttachment()) ? oldRoom.getAttachment(): "暂无");
                message.put("newName", StringUtils.isNotBlank(room.getAttachment()) ? room.getAttachment(): "暂无");
                messageArr.add(message);
            }

            if (!Objects.equals(oldRoom.getOrders(), room.getOrders())) {
                message = new JSONObject();
                message.put("name", "排序");
                message.put("oldName", oldRoom.getOrders());
                message.put("newName", room.getOrders());
                messageArr.add(message);
            }
        }
        return messageArr;
    }

    /**
     * 统计 建筑面积 与 实际使用面积
     * @param list
     * @param plan
     * @param use
     */
    private void statisticsHelper (List<Room> list, AtomicReference<Float> plan, AtomicReference<Float> use) {
        if (0 >= list.size()) {
            return;
        }

        list.forEach(item-> {
            if (StringUtils.isNotBlank(item.getArea())) {
                plan.updateAndGet(v -> new Float((float) (v + (Float.parseFloat(item.getArea())))));
            }
            if (StringUtils.isNotBlank(item.getUseArea())) {
                use.updateAndGet(v -> new Float((float) (v + (Float.parseFloat(item.getUseArea())))));
            }
        });

    }

    /**
     * 表格导入数据处理
     * @param roomIo
     * @param successNum
     * @param errorNum
     */
    private void importExcelHelper (RoomIo roomIo, AtomicInteger successNum, AtomicInteger errorNum) {

        String campusName = roomIo.getCampusName();
        String buildingName = roomIo.getBuildingName();
        String unitName = roomIo.getUnitName();
        String floorName = roomIo.getFloorName();

        boolean checkFlag =
                StringUtils.isBlank(campusName) || StringUtils.isBlank(buildingName) || StringUtils.isBlank(unitName) || StringUtils.isBlank(floorName) || StringUtils.isBlank(roomIo.getRoomCode())  || StringUtils.isBlank(roomIo.getArea()) || StringUtils.isBlank(roomIo.getUseArea()) || StringUtils.isBlank(roomIo.getLivingRoom()) || StringUtils.isBlank(roomIo.getOrient()) || null == roomIo.getIsElevator() || null == roomIo.getFloorType() || null == roomIo.getRoomType() || null == roomIo.getPayWay() || null == roomIo.getIsRent() || null == roomIo.getTenancyWay() || null == roomIo.getUseState() || null== roomIo.getIsFull() || StringUtils.isBlank(roomIo.getTemplateName());

        if (checkFlag) {
            errorNum.getAndIncrement();
            return;
        }

        Room room = new Room();
        BeanUtils.copyProperties(roomIo, room);

        Campus campus = campusService.getByName(campusName);

        if (null == (campus) && Objects.isNull(campus.getId())) {
            errorNum.getAndIncrement();
            return;
        }
        room.setCampusId(campus.getId());

        Building building = buildingService.getByCampusIdAndName(campus.getId(), buildingName);

        if (null == (building) || Objects.isNull(building.getId())) {
            errorNum.getAndIncrement();
            return;
        }
        room.setBuildingId(building.getId());

        Unit unit = unitService.getByCIDAndBIDAndName(campus.getId(), building.getId(), unitName);

        if (null == (unit) || Objects.isNull(unit.getId())) {
            errorNum.getAndIncrement();
            return;
        }
        room.setUnitId(unit.getId());

        Floor floor = floorService.getByOtherIdAndName(campus.getId(), building.getId(), unit.getId(),
                floorName);
        if (null == (floor) || Objects.isNull(floor.getId())) {
            errorNum.getAndIncrement();
            return;
        }
        room.setFloorId(floor.getId());

        if (!RoomValidation.checkElevator(room.getIsElevator())) {
            errorNum.getAndIncrement();
            return;
        }

        room.setParentId(room.getCampusId() + "-" + room.getBuildingId() + "-" + room.getUnitId() + "-" + room.getFloorId());

        ContractTemplate contractTemplate = contractTemplateService.getByName(roomIo.getTemplateName());
        if (null == contractTemplate || Objects.isNull(contractTemplate.getId())) {
            errorNum.getAndIncrement() ;
            return;
        }
        room.setContractTemplateId(contractTemplate.getId());

        if (!RoomValidation.checkFloorType(room.getFloorType())) {
            errorNum.getAndIncrement();
            return;
        }

        if (!RoomValidation.checkRoomType(room.getRoomType())) {
            errorNum.getAndIncrement();
            return;
        }

        if (!RoomValidation.checkPayWay(room.getPayWay())) {
            errorNum.getAndIncrement();
            return;
        }

        if (!RoomValidation.checkIsRent(room.getIsRent())) {
            errorNum.getAndIncrement();
            return;
        }

        if (RoomConstant.RENT_ZERO == room.getIsRent() && StringUtils.isBlank(room.getRent())) {
            errorNum.getAndIncrement();
            return;
        } else if (RoomConstant.RENT_ONE == room.getIsRent() && Objects.isNull(roomIo.getRentName())) {
            errorNum.getAndIncrement();
            return;
        }
        if (StringUtils.isBlank(room.getRent())) {
            room.setRent("0");
        }

        if (StringUtils.isNotBlank(roomIo.getRentName())) {
            Rent rent = rentService.getByName(roomIo.getRentName());
            room.setRentId(rent.getId());
        }

        if (!RoomValidation.checkTenancyWay(room.getTenancyWay())) {
            errorNum.getAndIncrement();
            return;
        }

        if (!RoomValidation.checkUseState(room.getUseState())) {
            errorNum.getAndIncrement();
            return;
        }

        if (!RoomValidation.checkIsFull(room.getIsFull())) {
            errorNum.getAndIncrement();
            return;
        }

//        Lesseemanage lesseemanage = lesseemanageService.getByName(roomIo.getLesseeManageName());
//
//        if (null == lesseemanage || Objects.isNull(lesseemanage.getId())) {
//            errorNum.getAndIncrement();
//            return;
//        }

//        room.setLesseemanageId(lesseemanage.getId());

        try {
            this.save(room);
            successNum.getAndIncrement();
        } catch (Exception e) {
            e.printStackTrace();
            errorNum.getAndIncrement();
            return;
        }
    }
}
